#!/bin/bash

# set -x

#
# config network for docker conntainer with --net=none option
# reference: https://github.com/jpetazzo/pipework
#

IFNAME=br0
CONTAINER_IFNAME=eth1
FAMILY_FLAG="-4"

function try_exec() {
	$@
	if [ $? -ne 0 ]
	then
		exit 1
	fi
}

function create_container_network() {
  if [ -z "$1" ]; then
    return 1
  fi
  cname=$1
  GATEWAY=`route -n | grep $IFNAME | grep UG | awk '{print $2}'`
	if [ $? -ne 0 ]
	then
		return 1
	fi

	DOCKERPID=`docker inspect --format='{{ .State.Pid }}' "$cname"`
	if [ $? -ne 0 ]
	then
		return 1
 	fi
	DOCKERCID=`docker inspect --format='{{ .ID }}' "$cname"`
	if [ $? -ne 0 ]
        then
          return 1
        fi

	DOCKERCNAME=`docker inspect --format='{{ .Name }}' "$cname"`
	if [ $? -ne 0 ]
    then
		return 1
	fi


	NSPID=$DOCKERPID

	LOCAL_IFNAME="v${CONTAINER_IFNAME}pl${NSPID}"
	GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}"
	MTU=`ip link show "$IFNAME" | awk '{print $5}'`
	if [ $? -ne 0 ]
    then
    	return 1
    fi

	#
	try_exec mkdir -p /var/run/netns
	try_exec rm -f "/var/run/netns/$NSPID"
	try_exec ln -s "/proc/$NSPID/ns/net" "/var/run/netns/$NSPID"

	# create veth-pair
	try_exec ip link add name "$LOCAL_IFNAME" mtu "$MTU" type veth peer name "$GUEST_IFNAME" mtu "$MTU"
	try_exec ip link set "$LOCAL_IFNAME" master "$IFNAME" > /dev/null 2>&1
	try_exec ip link set "$LOCAL_IFNAME" up

	# set veth-pair with container namespace
	try_exec ip link set "$GUEST_IFNAME" netns "$NSPID"
	try_exec ip netns exec "$NSPID" ip link set "$GUEST_IFNAME" name "$CONTAINER_IFNAME"
	# Remove NSPID to avoid `ip netns` catch it.
	try_exec rm -f "/var/run/netns/$NSPID"
}

function create() {
	# FROM centos:7
	# RUN yum install -y net-tools dhclient
	try_exec docker run -itd --cap-add NET_ADMIN --net=none --name ${GUESTNAME}_dhcp registry.cn-hangzhou.aliyuncs.com/wxx_image/centos:wxx
	try_exec create_container_network ${GUESTNAME}_dhcp
	try_exec docker exec -it ${GUESTNAME}_dhcp dhclient $CONTAINER_IFNAME >/dev/null

  try_exec docker run -itd --net container:${GUESTNAME}_dhcp --name $GUESTNAME $GUESTENV $GUESTVOLUME $IMAGENAME $GUESTARG
	GUSET_IP=$(docker exec -it ${GUESTNAME}_dhcp ifconfig $CONTAINER_IFNAME | grep "inet" | awk '{ print $2}')
	GUEST_HOSTNAME=$(docker exec -it ${GUESTNAME} cat /etc/hostname)
	if [ -n "$GUSET_IP" ] && [ -n "$GUEST_HOSTNAME" ]; then
		docker exec -it ${GUESTNAME} bash -c "echo '$GUSET_IP $GUEST_HOSTNAME' >> /etc/hosts"
	fi
}

function delete() {
	stat=` docker inspect --format {{.State.Status}} ${GUESTNAME}_dhcp`
	if [ "$stat" = "running" ]; then
		try_exec docker exec -it ${GUESTNAME}_dhcp dhclient -r $CONTAINER_IFNAME
	fi
	try_exec docker rm -f $GUESTNAME ${GUESTNAME}_dhcp
}

function start() {
  stat=` docker inspect --format {{.State.Status}} ${GUESTNAME}_dhcp`
	if [ "$stat" != "running" ]; then
		try_exec docker start ${GUESTNAME}_dhcp
		try_exec create_container_network ${GUESTNAME}_dhcp
		try_exec docker exec -it ${GUESTNAME}_dhcp dhclient $CONTAINER_IFNAME >/dev/null
	fi
	stat=` docker inspect --format {{.State.Status}} ${GUESTNAME}`
	if [ "$stat" != "running" ]; then
		try_exec docker start ${GUESTNAME}
	fi
	GUSET_IP=$(docker exec -it ${GUESTNAME}_dhcp ifconfig $CONTAINER_IFNAME | grep "inet" | awk '{ print $2}')
	GUEST_HOSTNAME=$(docker exec -it ${GUESTNAME} cat /etc/hostname)
	if [ -n "$GUSET_IP" ] && [ -n "$GUEST_HOSTNAME" ]; then
		docker exec -it ${GUESTNAME} bash -c "echo '$GUSET_IP $GUEST_HOSTNAME' >> /etc/hosts"
	fi
}

function usage() {
  echo "Usage:"
  echo "  dockerx run [-e ENV] [-v VOLUME] NAME IMAGE [ARG...]"
  echo "  dockerx rm NAME"
  echo "  dockerx start NAME"
}

function parse_run_arg() {
	while getopts ":e:v:" OPTION
  do
    case $OPTION in
      e ) GUESTENV="$GUESTENV --env $OPTARG";;
      v ) GUESTVOLUME="$GUESTVOLUME -v $OPTARG";;
      ? ) echo "Invalid option"
          exit 1;;
    esac
  done

  shift $(($OPTIND - 1))
  GUESTNAME=$1
  IMAGENAME=$2
  if [ -z "$GUESTNAME" ] && [ -z "$IMAGENAME" ]; then
    echo "Invalid NAME or IMAGE"
		exit 1
	fi
	shift 2
	GUESTARG=$*
}

function parse_rm_arg() {
  GUESTNAME=$1
  if [ -z "$GUESTNAME" ]; then
    echo "Invalid NAME"
    exit 1
  fi
}

function parse_start_arg() {
  GUESTNAME=$1
  if [ -z "$GUESTNAME" ]; then
    echo "Invalid NAME"
    exit 1
  fi
}

function main() {
  if [ $# -lt 1 ]; then
      usage
      exit 0
  fi
  OPTYPE=$1

	if [ $OPTYPE = "run" ]; then
	  shift 1
	  parse_run_arg $*
		create
	elif [ $OPTYPE = "rm" ]; then
	  shift 1
	  parse_rm_arg $*
		delete
	elif [ $OPTYPE = "start" ]; then
	  shift 1
	  parse_start_arg $*
		start
	else
	  echo "Invalid command"
    usage
		exit 1
	fi
	exit 0
}

main $@
